#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "sprtGraphic.h"
#include "HWISPRTPrinter.h"

extern void DoLog(char *pLogMsg,int logMsgLen);		// 日志记录函数;
extern char gLogBuf[1024];		// 日志记录缓冲区;


int m_iWidth=0;			// 实际宽度;
int m_iHeight=0;			// 实际高度;
int m_iColor = 0;                  // 颜色表
unsigned char *m_lpBuffer=NULL;			// 图形数据缓冲区;

// 校验用户bmp图像数据格式及初始化相关变量; 0:成功，其他：失败；
int InitUserBMP(const char *bitmap)
{
	int iLength		= 0;
	int iRealHeight	= 0;
	int iRealWidth  = 0;
	unsigned char *lpBuffer	= NULL;
	unsigned char *lpNewBuff= NULL;
	
	int dataOffset=0;

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMP() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));
	if(bitmap == NULL)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMP() bitmap == NULL");
		DoLog(gLogBuf,strlen(gLogBuf));
		return -1;
	}
	iLength =ValidUserBMP(bitmap,&dataOffset);
	if(iLength<=0)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMP() ValidUserBMP() fail! iLength=%d",iLength);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -2;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMP() ValidUserBMP() OK! iLength=%d,dataOffset=%d",iLength,dataOffset);
	DoLog(gLogBuf,strlen(gLogBuf));

	iRealHeight = (m_iHeight+7)/8;
	iRealHeight *= 8;
	iRealWidth  = (m_iWidth+31)/32;
	iRealWidth *= 32;
	//	lpBuffer =(unsigned char *) malloc(m_iHeight*iRealWidth);
	int iRealWidthByte=iRealWidth/8;
	int iRealHeightByte=iRealHeight/8;
	lpBuffer =(unsigned char *) malloc(m_iHeight*iRealWidthByte);
	memset(lpBuffer, 0, m_iHeight*iRealWidthByte);
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMP() iRealHeight=%d,iRealWidth=%d,iRealWidthByte=%d,iRealHeightByte=%d",iRealHeight,iRealWidth,iRealWidthByte,iRealHeightByte);
	DoLog(gLogBuf,strlen(gLogBuf));

	memcpy(lpBuffer,(unsigned char *)&bitmap[dataOffset],m_iHeight*iRealWidthByte);		// 真实的字节;

	//分配较大内存，来存储本地文件
	lpNewBuff = (unsigned char *)malloc(iRealHeight*iRealWidthByte);		// 分配高度为8的倍数个字节空间;
	memset(lpNewBuff, 0xff, iRealHeight*iRealWidthByte);
	ReverseBitmap(lpBuffer, lpNewBuff);
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMP() ReverseBitmap() OK! iRealHeight*iRealWidthByte=%d",iRealHeight*iRealWidthByte);
	DoLog(gLogBuf,strlen(gLogBuf));

	free(lpBuffer);
	lpBuffer = NULL;
	m_lpBuffer = lpNewBuff;

	//填充4字节边界缓冲
	//		if( (m_iWidth%4 != 0) )
	if( (m_iWidth%32 != 0) )		// 应该是32的倍数，不应该4，是4字节，应该为(m_iWidth%32!=0)； qzfeng 2015/02/09
	{
		FeedEmptyBit(m_lpBuffer, m_iHeight, m_iWidth, iRealWidth);
	}
	m_iWidth  = iRealWidth;

	return 0;
}

// 校验用户bmp图像数据格式及获得数据偏移量;
int ValidUserBMP(const char *bitmap,int *dataOffset)
{
	PBITMAPINFOHEADER pbih = NULL;
	PBITMAPFILEHEADER pbfh = NULL;
	char szBuff[256] = {0};
	//unsigned long dwRead = 0;
	int dataLen = 0;


	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserBMP() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));

	memcpy(szBuff,bitmap,sizeof(BITMAPFILEHEADER));

	if(szBuff[0]!=0x42||szBuff[1]!=0x4d)			// not "BM";
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserBMP() 格式不正确,不是BM开头，szBuff[0]=%02x,szBuff[1]=%02x",szBuff[0],szBuff[1]);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -1;
	}
	pbfh = (PBITMAPFILEHEADER)szBuff;
	*dataOffset=pbfh->bfOffBits;				// 数据偏移量;

	// 计算出文件的数据大小
	dataLen = pbfh->bfSize - (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+2*sizeof(RGBQUAD));	// 单色图所以是两个RGBQUAD(数组); qzfeng 2015/09/15

	memcpy(szBuff,(unsigned char *)&bitmap[sizeof(BITMAPFILEHEADER)],sizeof(BITMAPINFOHEADER));
	pbih = (PBITMAPINFOHEADER)szBuff;
	if(pbih->biBitCount != 1)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserBMP() 位深非1位，pbih->biBitCount=%d",pbih->biBitCount);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -2;
	}

	m_iWidth = pbih->biWidth;
	m_iHeight = pbih->biHeight;

	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserBMP() *dataOffset=%x,dataLen=%d,m_iWidth=%d,m_iHeight=%d",*dataOffset,dataLen,m_iWidth,m_iHeight);
	DoLog(gLogBuf,strlen(gLogBuf));

	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserBMP() finished.");
	DoLog(gLogBuf,strlen(gLogBuf));

	return dataLen;
}

// 打开bmp位图文件; 0:成功，其他：失败；
int InitBmpFile(unsigned char *szFile)
{
	FILE *hFile = NULL;
	int iLength		= 0;
	int iRealHeight	= 0;
	int iRealWidth  = 0;
	//unsigned long dwRead	= 0;
	unsigned char *lpBuffer	= NULL;
	unsigned char *lpNewBuff= NULL;
	int ret=-1;

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() begin...");
	DoLog(gLogBuf,(int)strlen(gLogBuf));
	if(szFile == NULL)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() szFile == NULL");
		DoLog(gLogBuf,strlen(gLogBuf));
		return -1;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() szFile=%s",szFile);
	DoLog(gLogBuf,strlen(gLogBuf));

	hFile=fopen((const char *)szFile,"rb");
	if(hFile==NULL)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() rb fopen() fail! hFile==NULL szFile=%s",szFile);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -2;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() rb fopen() OK! szFile=%s",szFile);
	DoLog(gLogBuf,strlen(gLogBuf));
	iLength =ValidBMP(hFile);
	if(iLength<=0)
	{
		fclose(hFile);
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() ValidBMP() fail! iLength=%d",iLength);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -3;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() ValidBMP() OK! iLength=%d",iLength);
	DoLog(gLogBuf,strlen(gLogBuf));

	iRealHeight = (m_iHeight+7)/8;
	iRealHeight *= 8;
	iRealWidth  = (m_iWidth+31)/32;
	iRealWidth *= 32;
	//	lpBuffer =(unsigned char *) malloc(m_iHeight*iRealWidth);
	int iRealWidthByte=iRealWidth/8;
	int iRealHeightByte=iRealHeight/8;
	lpBuffer =(unsigned char *)malloc(m_iHeight*iRealWidthByte);
	memset(lpBuffer, 0, m_iHeight*iRealWidthByte);

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() iRealHeight=%d,iRealWidth=%d,iRealWidthByte=%d,iRealHeightByte=%d",iRealHeight,iRealWidth,iRealWidthByte,iRealHeightByte);
	DoLog(gLogBuf,strlen(gLogBuf));

	ret=fread(lpBuffer,1,m_iHeight*iRealWidthByte,hFile);		// 真实的字节;
	if(ret!=m_iHeight*iRealWidthByte)
	{
		if(lpBuffer!=NULL)
		{
			free(lpBuffer);
			lpBuffer=NULL;
		}
		fclose(hFile);
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() fread() fail! m_iHeight*iRealWidthByte=%d,ret=%d",m_iHeight*iRealWidthByte,ret);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -4;
	}
	// 不再需要文件句柄，将其关闭
	fclose(hFile);
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() lpBuffer fread() OK! m_iHeight*iRealWidthByte=%d",m_iHeight*iRealWidthByte);
	DoLog(gLogBuf,strlen(gLogBuf));

	//分配较大内存，来存储本地文件
	lpNewBuff = (unsigned char *)malloc(iRealHeight*iRealWidthByte);		// 分配高度为8的倍数个字节空间;
	memset(lpNewBuff, 0xff, iRealHeight*iRealWidthByte);
	ReverseBitmap(lpBuffer, lpNewBuff);
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() ReverseBitmap() OK! iRealHeight*iRealWidthByte=%d",iRealHeight*iRealWidthByte);
	DoLog(gLogBuf,strlen(gLogBuf));

	if(lpBuffer!=NULL)
	{
		free(lpBuffer);
		lpBuffer=NULL;
	}

	m_lpBuffer = lpNewBuff;

	//填充4字节边界缓冲
	//		if( (m_iWidth%4 != 0) )
	if( (m_iWidth%32 != 0) )		// 应该是32的倍数，不应该4，是4字节，应该为(m_iWidth%32!=0)； qzfeng 2015/02/09
	{
		FeedEmptyBit(m_lpBuffer, m_iHeight, m_iWidth, iRealWidth);
	}
	m_iWidth  = iRealWidth;

	sprintf(gLogBuf,"m_iHeight=%d,m_iWidth=%d",m_iHeight,m_iWidth);
	DoLog(gLogBuf,strlen(gLogBuf));

	/*
	   int m=0;
	   int n=0;
	   for(m=0; m<m_iHeight; m++)
	   {
	   for(n=0; n<m_iWidth; n++)
	   {
	   m_lpBuffer[m*m_iWidth+n]=~m_lpBuffer[m*m_iWidth+n];
	   }
	   }
	 */

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitBmpFile() end.");
	DoLog(gLogBuf,strlen(gLogBuf));

	return 0;
}

// 查询文件是否符合规定，如果符合单色位图
// 则记录文件的尺寸，并且返回数据的尺寸
int ValidBMP(FILE *hBmp)
{


	//PBITMAPINFOHEADER pbih = NULL;
	//pbih=(struct BITMAPINFOHEADER *)malloc(sizeof(struct BITMAPINFOHEADER));

	//PBITMAPFILEHEADER pbfh = NULL;
	//pbfh=(struct BITMAPFILEHEADER *)malloc(sizeof(struct BITMAPFILEHEADER));
	BITMAPINFOHEADER pbih;
	BITMAPFILEHEADER pbfh;

	unsigned char szBuff[256] = {0};
	
	int dataLen = 0;
	int dataOffset=0;
	RGBQUAD rgb[2] = {0};

	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));

	int ret=fread(szBuff,1,sizeof(BITMAPFILEHEADER),hBmp);

	if(ret==sizeof(BITMAPFILEHEADER))
	{
		if((szBuff[0]!=0x42)&&(szBuff[0]!=0x4d))			// not "BM";
		{
			sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() 格式不正确,不是BM开头，szBuff[0]=%02x,szBuff[1]=%02x,bfType=%d,bfSize=%d",szBuff[0],szBuff[1],pbfh.bfType,pbfh.bfSize);
			DoLog(gLogBuf,strlen(gLogBuf));
			return -1;
		}

		//pbfh = (PBITMAPFILEHEADER)szBuff;
		pbfh.bfType = (szBuff[0]<<8)|szBuff[1];
		pbfh.bfSize = szBuff[5]<<24|szBuff[4]<<16|szBuff[3]<<8|szBuff[2];
		pbfh.bfReserved1 = (szBuff[7]<<8)|szBuff[6];
		pbfh.bfReserved2 = (szBuff[9]<<8)|szBuff[8];
		pbfh.bfOffBits = szBuff[13]<<24|szBuff[12]<<16|szBuff[11]<<8|szBuff[10];

		sprintf(gLogBuf,"pbfh->bfType=%x,pbfh->bfSize=%x,pbfh->bfReserved1=%x,pbfh->bfReserved2=%x,pbfh->bfOffBits=%x",pbfh.bfType,pbfh.bfSize,pbfh.bfReserved1,pbfh.bfReserved2,pbfh.bfOffBits);
		DoLog(gLogBuf,strlen(gLogBuf));

		dataOffset=pbfh.bfOffBits;				// 数据偏移量;
		// 计算出文件的数据大小
		dataLen = pbfh.bfSize - (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+2*sizeof(RGBQUAD));	// 单色图所以是两个RGBQUAD(数组); qzfeng 2015/09/15

		sprintf(gLogBuf,"BITMAPFILEHEADER=%d,BITMAPINFOHEADER=%d,RGBQUAD=%d",(int)sizeof(BITMAPFILEHEADER),(int)sizeof(BITMAPINFOHEADER),(int)sizeof(RGBQUAD));
		DoLog(gLogBuf,strlen(gLogBuf));


		ret=fread(szBuff,1,sizeof(BITMAPINFOHEADER),hBmp);


		/*pbih->biSize = szBuff[17]<<32|szBuff[16]<<16|szBuff[15]<<8|szBuff[14];
		  pbih->biWidth = szBuff[21]<<32|szBuff[20]<<16|szBuff[19]<<8|szBuff[18];
		  pbih->biHeight = szBuff[25]<<32|szBuff[24]<<16|szBuff[23]<<8|szBuff[22];
		  pbih->biPlanes = (szBuff[27]<<8)|szBuff[26];
		  pbih->biBitCount = (szBuff[29]<<8)|szBuff[28];
		  pbih->biCompression = szBuff[33]<<32|szBuff[32]<<16|szBuff[31]<<8|szBuff[30];
		  pbih->biSizeImage = szBuff[37]<<32|szBuff[36]<<16|szBuff[35]<<8|szBuff[34];
		  pbih->biXPelsPerMeter = szBuff[41]<<32|szBuff[40]<<16|szBuff[39]<<8|szBuff[38];
		  pbih->biYPelsPerMeter = szBuff[45]<<32|szBuff[44]<<16|szBuff[43]<<8|szBuff[42];
		  pbih->biClrUsed = szBuff[49]<<32|szBuff[48]<<16|szBuff[47]<<8|szBuff[46];
		  pbih->biClrImportant = szBuff[53]<<32|szBuff[52]<<16|szBuff[51]<<8|szBuff[50];*/

		pbih.biSize = szBuff[3]<<24|szBuff[2]<<16|szBuff[1]<<8|szBuff[0];
		pbih.biWidth = szBuff[7]<<24|szBuff[6]<<16|szBuff[5]<<8|szBuff[4];
		pbih.biHeight = szBuff[11]<<24|szBuff[10]<<16|szBuff[9]<<8|szBuff[8];
		pbih.biPlanes = (szBuff[13]<<8)|szBuff[12];
		pbih.biBitCount = (szBuff[15]<<8)|szBuff[14];
		pbih.biCompression = szBuff[19]<<24|szBuff[18]<<16|szBuff[17]<<8|szBuff[16];
		pbih.biSizeImage = szBuff[23]<<24|szBuff[22]<<16|szBuff[21]<<8|szBuff[20];
		pbih.biXPelsPerMeter = szBuff[27]<<24|szBuff[26]<<16|szBuff[25]<<8|szBuff[24];
		pbih.biYPelsPerMeter = szBuff[31]<<24|szBuff[30]<<16|szBuff[29]<<8|szBuff[28];
		pbih.biClrUsed = szBuff[35]<<24|szBuff[34]<<16|szBuff[33]<<8|szBuff[32];
		pbih.biClrImportant = szBuff[39]<<24|szBuff[38]<<16|szBuff[37]<<8|szBuff[36];

		sprintf(gLogBuf,"pbih->biSize=%x,pbih->biWidth=%x,pbih->biHeight=%x,pbih->biPlanes=%x,pbih->biBitCount=%x,pbih->biCompression=%x,pbih->biSizeImage=%x,pbih->biXPelsPerMeter=%x,pbih->biYPelsPerMeter=%x,pbih->biClrUsed=%x,pbih->biClrImportant=%x",pbih.biSize,pbih.biWidth,pbih.biHeight,pbih.biPlanes,pbih.biBitCount,pbih.biCompression,pbih.biSizeImage,pbih.biXPelsPerMeter,pbih.biYPelsPerMeter,pbih.biClrUsed,pbih.biClrImportant);
		DoLog(gLogBuf,strlen(gLogBuf));

		if(ret==sizeof(BITMAPINFOHEADER))
		{
			//pbih = (PBITMAPINFOHEADER)szBuff;
			if(pbih.biBitCount != 1)
			{
				sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() 位深非1位，pbih->biBitCount=%d,ret=%d,sizeof(BITMAPINFOHEADER)=%d",pbih.biBitCount,ret,(int)sizeof(BITMAPINFOHEADER));
				DoLog(gLogBuf,strlen(gLogBuf));
				return -2;
			}

			m_iWidth = pbih.biWidth;
			m_iHeight = pbih.biHeight;

			//偏移文件指针到数据缓存区
			fread(rgb, 1, sizeof(RGBQUAD)*2, hBmp);
			if (0x00 == rgb[0].rgbBlue && 0x00 == rgb[0].rgbGreen && 0x00 == rgb[0].rgbRed){
				m_iColor = 0;
			}else{
				m_iColor = 1;
			}

			ret=fseek(hBmp,dataOffset,SEEK_SET);
			if(ret!=0)
			{
				sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() fseek() fail! dataOffset=%d",dataOffset);
				DoLog(gLogBuf,strlen(gLogBuf));
				return -3;
			}
		}
		else
		{
			sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() BITMAPINFOHEADER fread() fail! ret=%d",ret);
			DoLog(gLogBuf,strlen(gLogBuf));
			return -4;

		}
	}
	else
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() BITMAPFILEHEADER fread() fail! ret=%d",ret);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -5;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() dataOffset=%x,dataLen=%d,m_iWidth=%d,m_iHeight=%d",dataOffset,dataLen,m_iWidth,m_iHeight);
	DoLog(gLogBuf,strlen(gLogBuf));

	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidBMP() finished.");
	DoLog(gLogBuf,strlen(gLogBuf));

	//free(pbfh);
	//free(pbih);

	return dataLen;
}

// 反向处理图像
void ReverseBitmap(unsigned char  *lpOrg, unsigned char *lpBuff)
{
	long iWidth = (m_iWidth+31)/32*4;
	int i=0;
	for(i=m_iHeight-1; i>=0; --i)
	{
		memcpy(lpBuff+( (m_iHeight-i-1) * iWidth ), lpOrg+(i*iWidth), iWidth);
	}
	return;
}
// 处理掉图像的填充位
void FeedEmptyBit(unsigned char *lpBuff, int iHeight, int iOrgWid, int iObtWid)
{
	long padByte = (iObtWid-iOrgWid)/8;				// 获得了需要填充的字节数（iObtWid为32位的倍数）; qzfeng 2015/09/15
	//long padBits = (iObtWid-iOrgWid)%8;					// 获得了需要填充的位数(原始位图不够一个字节);	qzfeng 2015/09/15
	long orgByte = iOrgWid/8;				// 获得了原始位图的字节宽度; qzfeng 2015/09/15
	long orgBits = iOrgWid%8;				// 获得了原始位图不到一个字节的位数; qzfeng 2015/09/15
	int tv		 = 0;
	long iWidth = (m_iWidth+31)/32*4;		// 获得了填充后是32位的倍数的宽度，应和iObtWid相等; qzfeng 2015/09/15

	int i=0;
	for(i=0; i<iHeight; i++)
	{
		if (0 == m_iColor){  // subo 20200429 根据BMP颜色表决定填充位
			{
				lpBuff[iWidth*i+orgByte] |= 0xff>>orgBits;
			}
			tv = iWidth*i+orgByte+1;
			memset(lpBuff+tv, 0xff, padByte); 
		}else{
			{
				lpBuff[iWidth*i+orgByte] |= 0x00>>orgBits;
			}
			tv = iWidth*i+orgByte+1;
			memset(lpBuff+tv, 0x00, padByte); 
		}
	}
	return;
}

//下载位图1B，FE
// 返回数据长度;  <0:失败;
int InitDownloadImage(unsigned char *path, int position)
{
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));

	if (path==NULL)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() path=NULL!");
		DoLog(gLogBuf,strlen(gLogBuf));
		return -1;
	}

	FILE *hFile=fopen((const char *)path,"rb");
	if(hFile==NULL)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() rb fopen() fail! hFile==NULL path=%s",path);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -2;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() rb fopen() OK! path=%s",path);
	DoLog(gLogBuf,strlen(gLogBuf));

	int dataOffset=0;
	int iLength =ValidBMP(hFile);
	if(iLength<=0)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() ValidBMP() fail! iLength=%d",iLength);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -3;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() ValidBMP() OK! iLength=%d,dataOffset=%d",iLength,dataOffset);
	DoLog(gLogBuf,strlen(gLogBuf));


	int BmpHeight=m_iHeight;
	int BmpWidth=m_iWidth;
	int pianyi = 0;

	if(BmpWidth % 32 != 0)						// 必须是32位的倍数; qzfeng 2015/09/15
	{
		pianyi = 32 - (BmpWidth % 32);			// 需补成32位倍数的位数; qzfeng 2015/09/15
	}

	int width=(BmpWidth+pianyi)/8;			// 补成4字节倍数后的宽度字节; qzfeng 2015/09/15
	int realbyte=(BmpWidth+7)/8;			// 真实的字节; qzfeng 2015/09/15
	int pianpixel=realbyte*8-BmpWidth;		// 不到一个字节的多出的位数; qzfeng 2015/09/15

	int length = BmpHeight*realbyte+7;		// 预留7个字节用来存储7字节指令; qzfeng 2015/09/15
	char *strdata=(char *)malloc(length);

	unsigned char *lpBuffer =(unsigned char *)malloc(BmpHeight*width);
	memset(lpBuffer, 0, BmpHeight*width);

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() BmpHeight=%d,width=%d,BmpHeight*width=%d,realbyte=%d,length=%d,pianpixel=%02x",BmpHeight,width,BmpHeight*width,realbyte,length,pianpixel);
	DoLog(gLogBuf,strlen(gLogBuf));

	int ret=fread(lpBuffer,1,BmpHeight*width,hFile);		// 真实的字节;
	if(ret!=BmpHeight*width)
	{
		if(lpBuffer!=NULL)
		{
			free(lpBuffer);
			lpBuffer=NULL;
		}
		fclose(hFile);
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() fread() fail! BmpHeight*width=%d,ret=%d",BmpHeight*width,ret);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -4;
	}
	// 不再需要文件句柄，将其关闭
	fclose(hFile);
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() lpBuffer fread() OK! BmpHeight*width=%d",BmpHeight*width);
	DoLog(gLogBuf,strlen(gLogBuf));

	int j=0;
	int i=0;
	for(j = 0;j < BmpHeight; j++)
	{
		for(i = 0; i < realbyte; i++)
		{
			strdata[BmpHeight * realbyte - (j + 1) * realbyte + i + 7] = (char)(~lpBuffer[j * width + i]);		// 倒序排;
		}
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() strdata OK! j=%d,i=%d",j,i);
	DoLog(gLogBuf,strlen(gLogBuf));

	strdata[0] = 0x1B;
	strdata[1] = 0xFE; //横向取模
	strdata[2] = position;

	strdata[3] = realbyte % 256;
	strdata[4] = realbyte / 256;

	strdata[5] = BmpHeight % 256;
	strdata[6] = BmpHeight / 256;

	switch(pianpixel)
	{
		case 0:
			break;
		case 1:
			for(i=0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xfe;		// 7个字节的指令; 将不足一个字节的位数补0;  qzfeng 2015/09/15
			}
			break;
		case 2:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xfc;
			}
			break;
		case 3:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xf8;
			}
			break;
		case 4:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xf0;
			}
			break;
		case 5:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xe0;
			}
			break;
		case 6:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xc0;
			}
			break;
		case 7:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0x80;
			}
			break;
	}

	if(lpBuffer!=NULL)
	{
		free(lpBuffer);
		lpBuffer=NULL;
	}
	m_lpBuffer = (unsigned char *)strdata;

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitDownloadImage() end. length=%d",length);
	DoLog(gLogBuf,strlen(gLogBuf));

	return length;
}

//下载位图1B，FE
// 返回数据长度;  <0:失败;
int InitUserBMPDownloadImage(unsigned char *img, int position)
{
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));

	if (img==NULL)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() path=NULL!");
		DoLog(gLogBuf,strlen(gLogBuf));
		return -1;
	}

	int dataOffset=0;
	int iLength =ValidUserBMP((const char *)img,&dataOffset);
	if(iLength<=0)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() ValidUserBMP() fail! iLength=%d",iLength);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -2;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() ValidUserBMP() OK! iLength=%d,dataOffset=%d",iLength,dataOffset);
	DoLog(gLogBuf,strlen(gLogBuf));

	int BmpHeight=m_iHeight;
	int BmpWidth=m_iWidth;
	int pianyi = 0;

	if(BmpWidth % 32 != 0)						// 必须是32位的倍数; qzfeng 2015/09/15
	{
		pianyi = 32 - (BmpWidth % 32);			// 需补成32位倍数的位数; qzfeng 2015/09/15
	}

	int width=(BmpWidth+pianyi)/8;			// 补成4字节倍数后的宽度字节; qzfeng 2015/09/15
	int realbyte=(BmpWidth+7)/8;			// 真实的字节; qzfeng 2015/09/15
	int pianpixel=realbyte*8-BmpWidth;		// 不到一个字节的多出的位数; qzfeng 2015/09/15

	int length = BmpHeight*realbyte+7;		// 预留7个字节用来存储7字节指令; qzfeng 2015/09/15
	char *strdata=(char *)malloc(length);

	unsigned char *lpBuffer =(unsigned char *)malloc(BmpHeight*width);
	memset(lpBuffer, 0, BmpHeight*width);

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() BmpHeight=%d,width=%d,BmpHeight*width=%d,realbyte=%d,length=%d,pianpixel=%02x",BmpHeight,width,BmpHeight*width,realbyte,length,pianpixel);
	DoLog(gLogBuf,strlen(gLogBuf));

	memcpy(lpBuffer,(unsigned char *)&img[dataOffset],BmpHeight*width);		// 真实的字节;
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() lpBuffer memcpy OK! dataOffset=%d,BmpHeight=%d,width=%d,BmpHeight*width=%d",dataOffset,BmpHeight,width,BmpHeight*width);
	DoLog(gLogBuf,strlen(gLogBuf));

	int j=0;
	int i=0;
	for(j = 0;j < BmpHeight; j++)
	{
		for(i = 0; i < realbyte; i++)
		{
			strdata[BmpHeight * realbyte - (j + 1) * realbyte + i + 7] = (char)(~lpBuffer[j * width + i]);		// 倒序排;
		}
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() strdata OK! j=%d,i=%d",j,i);
	DoLog(gLogBuf,strlen(gLogBuf));

	strdata[0] = 0x1B;
	strdata[1] = 0xFE; //横向取模
	strdata[2] = position;

	strdata[3] = realbyte % 256;
	strdata[4] = realbyte / 256;

	strdata[5] = BmpHeight % 256;
	strdata[6] = BmpHeight / 256;

	i = 0;
	switch(pianpixel)
	{
		case 0:
			break;
		case 1:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xfe;		// 7个字节的指令; 将不足一个字节的位数补0;  qzfeng 2015/09/15
			}
			break;
		case 2:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xfc;
			}
			break;
		case 3:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xf8;
			}
			break;
		case 4:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xf0;
			}
			break;
		case 5:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xe0;
			}
			break;
		case 6:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0xc0;
			}
			break;
		case 7:
			for(i = 0; i < BmpHeight; i++)
			{
				strdata[(i + 1) * realbyte + 6]=strdata[(i + 1) * realbyte + 6] & 0x80;
			}
			break;
	}

	if(lpBuffer!=NULL)
	{
		free(lpBuffer);
		lpBuffer=NULL;
	}
	m_lpBuffer = (unsigned char *)strdata;

	sprintf(gLogBuf,"qzf at sprtGraphic.c InitUserBMPDownloadImage() end. length=%d",length);
	DoLog(gLogBuf,strlen(gLogBuf));

	return length;
}


// 校验用户bmp图像数据格式及获得数据大小;
// >0:数据大小，其他：失败;
int GetUserDownLoadBMPSize(unsigned char *bitmap)
{
	PBITMAPINFOHEADER pbih = NULL;
	PBITMAPFILEHEADER pbfh = NULL;
	char szBuff[256] = {0};
	//unsigned long dwRead = 0;
	int dataLen = 0;


	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserDownLoadBMP() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));

	memcpy(szBuff,bitmap,sizeof(BITMAPFILEHEADER));

	if((szBuff[0]!=0x42)||(szBuff[1]!=0x4d))			// not "BM";
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserDownLoadBMP() 格式不正确,不是BM开头，szBuff[0]=%02x,szBuff[1]=%02x",szBuff[0],szBuff[1]);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -1;
	}
	pbfh = (PBITMAPFILEHEADER)szBuff;

	// 计算出文件的数据大小
	dataLen = pbfh->bfSize - (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+2*sizeof(RGBQUAD));	// 单色图所以是两个RGBQUAD(数组); qzfeng 2015/09/15

	memcpy(szBuff,(unsigned char *)&bitmap[sizeof(BITMAPFILEHEADER)],sizeof(BITMAPINFOHEADER));
	pbih = (PBITMAPINFOHEADER)szBuff;
	if(pbih->biBitCount != 1)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserDownLoadBMP() 位深非1位，pbih->biBitCount=%d",pbih->biBitCount);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -2;
	}

	sprintf(gLogBuf,"qzf at sprtGraphic.c ValidUserDownLoadBMP() finished.");
	DoLog(gLogBuf,strlen(gLogBuf));

	return dataLen;
}
// 查询文件是否符合规定，如果符合单色位图
// 则记录文件的尺寸，并且返回数据的尺寸
int GetValidBMPFileSize(unsigned char *szFile)
{
	PBITMAPINFOHEADER pbih = NULL;
	PBITMAPFILEHEADER pbfh = NULL;
	char szBuff[256] = {0};
	int dataLen = 0;

	sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));

	FILE *hFile=fopen((const char *)szFile,"rb");
	if(hFile==NULL)
	{
		sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() rb fopen() fail! hFile==NULL szFile=%s",szFile);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -1;
	}
	sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() rb fopen() OK! szFile=%s",szFile);
	DoLog(gLogBuf,strlen(gLogBuf));

	int ret=fread(szBuff,1,sizeof(BITMAPFILEHEADER),hFile);

	if(ret==sizeof(BITMAPFILEHEADER))
	{
		if((szBuff[0]!=0x42)||(szBuff[1]!=0x4d))			// not "BM";
		{
			sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() 格式不正确,不是BM开头，szBuff[0]=%02x,szBuff[1]=%02x",szBuff[0],szBuff[1]);
			DoLog(gLogBuf,strlen(gLogBuf));
			return -2;
		}
		pbfh = (PBITMAPFILEHEADER)szBuff;

		// 计算出文件的数据大小
		dataLen = pbfh->bfSize - (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+2*sizeof(RGBQUAD));	// 单色图所以是两个RGBQUAD(数组); qzfeng 2015/09/15

		ret=fread(szBuff,1,sizeof(BITMAPINFOHEADER),hFile);
		if(ret==sizeof(BITMAPINFOHEADER))
		{
			pbih = (PBITMAPINFOHEADER)szBuff;
			if(pbih->biBitCount != 1)
			{
				fclose(hFile);
				sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() 位深非1位，pbih->biBitCount=%d",pbih->biBitCount);
				DoLog(gLogBuf,strlen(gLogBuf));
				return -3;
			}
		}
		else
		{
			fclose(hFile);
			sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() BITMAPINFOHEADER fread() fail! ret=%d",ret);
			DoLog(gLogBuf,strlen(gLogBuf));
			return -4;

		}
	}
	else
	{
		fclose(hFile);
		sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() BITMAPFILEHEADER fread() fail! ret=%d",ret);
		DoLog(gLogBuf,strlen(gLogBuf));
		return -5;
	}
	fclose(hFile);

	sprintf(gLogBuf,"qzf at sprtGraphic.c GetValidBMPFileSize() finished.");
	DoLog(gLogBuf,strlen(gLogBuf));

	return dataLen;
}

//
// 重载函数，将图片数据转化为指令 1D 44 01 15 n 16 n ...
//
// 参数：
//		pszBuffer	解析后的缓冲区数据
//
// 返回值：
//		返回发送缓冲区的大小，以便后来程序调用
//
int MakeCmdBuffer(char **pszBuffer)
{

	sprintf(gLogBuf,"qzf at sprtGraphic.c MakeCmdBuffer() begin...");
	DoLog(gLogBuf,strlen(gLogBuf));

	int iw=0,ih=0;
	int ibl = 0;
	unsigned char para15 = 0x01;
	unsigned char para16 = 0x00;
	long lstrlen = 0;

	iw = m_iWidth/8;
	ih = m_iHeight;

	char * pszBuff = (char *)m_lpBuffer;
	unsigned char * szBuff = (unsigned char *)malloc(m_iWidth/4*m_iHeight); // 2倍于图片缓冲区；
	unsigned char * szBuffer = szBuff;
	if(!szBuffer)
		return 0;

	*szBuffer++  = 0x1d;
	*szBuffer++  = 0x76; //0x44;
	*szBuffer++  = 0x01;
	lstrlen += 3;

	int i=0;
	for(i=0; i<ih; ++i, ibl=0, para15=0x01, para16=0x00)
	{
		//识别是否是空行
		int j=0;
		for(j=0; j<iw; ++j)
		{
			if(m_lpBuffer[i*iw+j] == 0x00)
			{
				ibl++;
			}
			else
				break;
		}
		if(ibl == iw)
		{
			para15 += 0x01;
			continue;
		}

		*szBuffer++ = 0x15;
		*szBuffer++ = para15;

		*szBuffer++ = 0x16;
		*szBuffer++ = iw;
		lstrlen += 4;
		int k=0;
		for(k=0; k<iw; ++k)
		{
			if(0 == m_iColor){
				*szBuffer++ = ~pszBuff[i*iw+k];
			}else{
				*szBuffer++ = pszBuff[i*iw+k];
			}
		}
		lstrlen += iw;
	}

	*szBuffer++  = 0x1d;
	*szBuffer++  = 0x44;
	*szBuffer++  = 0x00;
	lstrlen += 3;

	*pszBuffer = (char *)szBuff;

	sprintf(gLogBuf,"qzf at sprtGraphic.c MakeCmdBuffer() end. lstrlen=%d",(int)lstrlen);
	DoLog(gLogBuf,strlen(gLogBuf));

	return lstrlen;
}
